package com.example.qt.ptplatform.controller;

import com.example.qt.ptplatform.dto.LeaderboardDto;
import com.example.qt.ptplatform.dto.TorrentReportDataDTO;
import com.example.qt.ptplatform.entity.*;
import com.example.qt.ptplatform.mapper.TorrentReportMapper;
import com.example.qt.ptplatform.mapper.UserMapper;
import com.example.qt.ptplatform.service.TorrentService;
import com.example.qt.ptplatform.service.UserService;
import com.example.qt.ptplatform.service.impl.LoginLogServiceImpl;
import com.example.qt.ptplatform.service.impl.UserServiceImpl;
import com.example.qt.ptplatform.utils.JsonResult;
import com.example.qt.ptplatform.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.example.qt.ptplatform.service.impl.InviteCodeServiceImpl;
import com.example.qt.ptplatform.service.impl.PromotionsServiceImpl;
import com.example.qt.ptplatform.network.ClientUploader;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.codec.binary.Base64;

import java.io.File;
import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.Date;


@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private InviteCodeServiceImpl inviteCodeServiceImpl;
    @Autowired
    private ClientUploader clientUploader;
    @Autowired
    private LoginLogServiceImpl loginLogServiceImpl;
    @Autowired
    private TorrentReportMapper torrentReportMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private TorrentService torrentService;
    @Autowired
    private PromotionsServiceImpl promotionsServiceImpl;

    @RequestMapping(value = "/checkCardTime", method = RequestMethod.POST)
    public boolean checkWhetherInDate(@RequestParam Integer user_id){
        if(userService.checkWhetherInDate(user_id)){ return true;}
        return false;
    }


    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public JsonResult registerUser(@RequestBody User user, @RequestParam String inviteCode) {
        try {
            System.out.println("邀请码" + inviteCode);
            // 验证邀请码
            if (inviteCode != null && !inviteCode.isEmpty()) {
                String inviteCodeValidationResult = inviteCodeServiceImpl.validateInviteCode(inviteCode);  // 使用注入的服务来验证邀请码
                System.out.println("邀请码"+inviteCodeValidationResult);
                if (!"邀请码验证成功".equals(inviteCodeValidationResult)) {
                    return JsonResult.error(inviteCodeValidationResult);  // 返回邀请码错误信息
                }
            }

            // 设置默认值：如果没有传递 level，则设置默认值
            if (user.getLevel() == null) {
                user.setLevel(1);  // 设置默认等级
            }

            // 设置 inviteCount 默认值
            if (user.getInviteCount() == null) {
                user.setInviteCount(0);  // 设置默认邀请数
            }

            // 设置 avatar_url 的默认值
            if (user.getAvatarUrl() == null) {
                user.setAvatarUrl("default_avatar_url.jpg"); // 可以替换为一个默认的头像URL
            }

            // 设置注册时间为当前时间
            if (user.getRegistrationDate() == null) {
                user.setRegistrationDate(new Date());  // 设置注册时间为当前时间
            }

            // 检查用户名是否已存在
            boolean usernameExists = userService.isUsernameExist(user.getUsername());
            if (usernameExists) {
                System.out.println("用户名已存在: " + user.getUsername()); // 打印日志
                return JsonResult.error("用户名已存在");
            }

            // 保存用户
            boolean saveResult = userService.save(user);
            if (saveResult) {
                return JsonResult.success(user, "用户注册成功");  // 这里的顺序应该是 (user, "用户注册成功")
            } else {
                System.out.println("保存用户失败: " + user.getUsername()); // 打印日志
                return JsonResult.error("用户注册失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error("用户注册失败");
        }
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public JsonResult loginUser(@RequestBody User user, HttpServletRequest request) {
        try {
            // 查找用户
            User foundUser = userService.findByUsername(user.getUsername());

            // 检查用户是否存在
            if (foundUser == null) {
                return JsonResult.error("用户名不存在");
            }

            // 严格检查封禁状态
            if (foundUser.getBanStatus() != null && foundUser.getBanStatus()) {
                // 如果被封禁，直接返回错误，不进行自动解封
                return JsonResult.error("账号已被封禁");
            }

            // 检查密码是否正确
            if (!foundUser.getPassword().equals(user.getPassword())) {
                return JsonResult.error("密码错误");
            }

            // 更新登录时间
            foundUser.setLastLoginTime(new Date());
            userService.updateById(foundUser);

            // 生成 access token
            String token = JwtUtil.generateToken(foundUser.getUsername());

            // 获取用户角色
            String role = foundUser.getRole();

            // 使用 Map 返回 token 和 role 信息
            Map<String, Object> data = new HashMap<>();
            data.put("token", token);
            data.put("role", role);
            data.put("user_id", foundUser.getUserId()); // 返回用户ID

            // 登录成功后记录登录日志
            loginLogServiceImpl.recordLoginLog(foundUser.getUserId(), request);

            // 返回登录成功的结果，包括 token、角色和用户ID
            return JsonResult.success(data, "登录成功");

        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error("登录失败");
        }
    }




    @PostMapping("/updateLikedTorrentsAndTags")
    public JsonResult updateLikedTorrentsAndTags(
            @RequestParam Integer user_id,
            @RequestParam Integer torrent_id) {
        try {
            userService.updateLikedTorrentsAndTags(user_id, torrent_id, "watch");
            return JsonResult.success("更新成功");
        } catch (Exception e) {
            return JsonResult.error("更新失败: " + e.getMessage());
        }
    }

    // 新增用户
    @RequestMapping(value = "/addUser", method = RequestMethod.POST)
    public JsonResult addUser(@RequestBody User user) {
        try {
            userService.save(user);
            return JsonResult.success("用户新增成功", user);
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error("用户新增失败");
        }
    }

    // 查询用户列表
    @RequestMapping(value = "/findUserList", method = RequestMethod.GET)
    public JsonResult findUserList() {
        return JsonResult.success(userService.list(), "查询成功");
    }

    // 个性化资源推荐
    @PostMapping("/recommendSimilarUsers")
    public JsonResult recommendSimilarUsers(@RequestParam Integer user_id) {
        return userService.recommendSimilarUsers(user_id);
    }

    // 热门资源推荐
    @PostMapping("/recommendHotTorrent")
    public JsonResult recommendHotTorrent(@RequestParam Integer user_id) {
        return userService.recommendHotTorrent(user_id);
    }

    /**
     * 获取某用户当前积分总额
     * @param userId 用户ID
     */
    @GetMapping("/userPoints")
    public JsonResult getUserTotalPoints(@RequestParam("userId") Integer userId) {
        Integer points = userService.getUserPoints(userId);
        return JsonResult.success(200, "当前积分查询成功", points);
    }

    // 积分兑换上传量接口
    @PostMapping("/exchange-upload")
    public JsonResult exchangeUpload(@RequestParam Integer userId, @RequestParam Integer pointsToExchange) {
        boolean success = userService.exchangeUpload(userId, pointsToExchange);
        if (success) {
            return JsonResult.success("兑换成功");
        } else {
            return JsonResult.error("兑换失败，积分不足");
        }
    }

    // 积分兑换邀请数接口
    @PostMapping("/exchange-invite")
    public JsonResult exchangeInvite(@RequestParam Integer userId, @RequestParam Integer pointsToExchange) {
        boolean success = userService.exchangeInvite(userId, pointsToExchange);
        if (success) {
            return JsonResult.success("兑换成功");
        } else {
            return JsonResult.error("兑换失败，积分不足");
        }
    }

    //积分兑换增量卡接口
    @PostMapping("/exchange-incremental-card")
    public JsonResult exchangeIncrementalCard(@RequestParam Integer userId) {
        boolean success = userService.exchangeIncrementalCard(userId, 500);//500积分兑换一次
        if (success) {
            return JsonResult.success("兑换成功");
        } else {
            return JsonResult.error("增量卡兑换失败，积分不足或已经拥有增量卡");
        }
    }

    // 获取用户等级及权限
    @GetMapping("/level")
    public JsonResult getUserLevel(@RequestParam Integer userId) {
        return userService.getUserLevelAndPermissions(userId);
    }

    @PostMapping("/updateCounts")
    public JsonResult updateUserCounts(@RequestBody UserRequest request) {
        System.out.println("Received user_id: " + request.getUserId());
        System.out.println("Received qb_username: " + request.getQbUsername());
        System.out.println("Received qb_password: " + request.getQbPassword());
        try {
            boolean result = clientUploader.updateUploadAndDownloadCount(request.getUserId(), request.getQbUsername(), request.getQbPassword());
            if (result) {
                return JsonResult.success(200, "上传量、下载量更新成功");
            } else {
                return JsonResult.error("更新失败", "无法获取上传量和下载量数据");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error("更新失败");
        }
    }

    @RequestMapping(value = "/updateTorrentSeedStatus", method = RequestMethod.POST)
    public JsonResult updateTorrentSeedStatus(@RequestBody TorrentStatusRequest request) {
        try {
            boolean result = clientUploader.updateTorrentSeedStatus(
                    request.getUserId(),
                    request.getFilename(),
                    request.getQbUsername(),
                    request.getQbPassword()
            );
            if (result) {
                return JsonResult.success("种子状态更新成功");
            } else {
                return JsonResult.error("种子状态更新失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error("更新失败");
        }
    }

    // 用户修改资料接口
    @PutMapping("/update")
    public JsonResult updateUser(@RequestBody User user) {
        try {
            boolean success = userService.updateUser(user);
            if (success) {
                return JsonResult.success("资料更新成功");
            } else {
                return JsonResult.error("资料更新失败");
            }
        } catch (Exception e) {
            return JsonResult.error("发生异常: " + e.getMessage());
        }
    }

    // 获取所有用户的积分排行榜
    @GetMapping("/leaderboard")
    public JsonResult getLeaderboard() {
        try {
            List<LeaderboardDto> leaderboard = userService.getLeaderboard();
            return JsonResult.success("排行榜获取成功", leaderboard);
        } catch (Exception e) {
            return JsonResult.error("获取排行榜失败: " + e.getMessage());
        }
    }

    @PostMapping("/updateUserData")
    public JsonResult updateUserData( @RequestBody Map<String, Integer> request) {
        // 查询torrent_report表，获取所有与该用户关联的数据
        Integer userId = request.get("userId");
        List<TorrentReportDataDTO> reports = torrentReportMapper.selectByUserId(userId);

        // 统计上传和下载的总量
        BigDecimal totalUploaded = BigDecimal.ZERO;
        BigDecimal totalDownloaded = BigDecimal.ZERO;

        for (TorrentReportDataDTO report : reports) {
            totalUploaded = totalUploaded.add(new BigDecimal(report.getUploaded()));
            totalDownloaded = totalDownloaded.add(new BigDecimal(report.getDownloaded()));
        }

        // 获取用户对象
        User user = userMapper.selectById(userId);
        if (user == null) {
            return JsonResult.error("用户不存在");
        }

        // 更新用户上传和下载总量
        user.setUploadCount(totalUploaded.floatValue());
        user.setDownloadCount(totalDownloaded.floatValue());

        // 保存更新后的用户数据
        userMapper.updateById(user);

        // 返回操作结果
        return JsonResult.success(200, "用户数据更新成功", null);
    }

    // 上传用户头像图片
    @PostMapping("/upload-avatar")
    public JsonResult uploadUserAvatar(@RequestParam("userId") Integer userId,
                                       @RequestParam("avatar") MultipartFile avatarFile) {
        try {
            // 检查图片文件是否为空
            if (avatarFile.isEmpty()) {
                return JsonResult.error("请选择要上传的图片");
            }

            // 获取文件的字节数组
            byte[] avatarBytes = avatarFile.getBytes();

            // 将字节数组转为 Base64 编码
            String base64Avatar = Base64.encodeBase64String(avatarBytes);

            // 更新用户头像的 Base64 编码
            User user = userMapper.selectById(userId);
            if (user != null) {
                user.setAvatarUrl(base64Avatar);  // 保存头像的 Base64 编码
                userMapper.updateById(user);  // 更新数据库中的用户数据
                return JsonResult.success("头像上传成功", user);
            } else {
                return JsonResult.error("用户不存在");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return JsonResult.error("文件上传失败");
        }
    }

    // 获取用户头像图片
    @GetMapping("/get-avatar")
    public JsonResult getUserAvatar(@RequestParam("userId") Integer userId) {
        try {
            // 获取用户信息
            User user = userMapper.selectById(userId);
            if (user != null) {
                // 获取头像的 Base64 编码
                String base64Avatar = user.getAvatarUrl();
                if (base64Avatar != null && !base64Avatar.isEmpty()) {
                    // 返回 Base64 编码的头像
                    return JsonResult.success(base64Avatar);
                } else {
                    return JsonResult.error("用户没有上传头像");
                }
            } else {
                return JsonResult.error("用户不存在");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error("获取头像失败");
        }
    }

    //测试增量卡函数的测试接口（不对外使用）
    // 测试增量卡上传量翻倍的接口
    @PostMapping("/updateUploadCountByDouble")
    public JsonResult updateUploadCountByDouble(@RequestParam("userId") Integer userId, @RequestParam("torrentId") Integer torrentId) {
        try {

            // 调用增量卡更新上传量的函数
            userService.updateUserUploadCountByDouble(userId, torrentId);
            return JsonResult.success("上传量更新成功");
        } catch (Exception e) {
            // 处理异常并返回错误信息
            return JsonResult.error("更新上传量失败", e.getMessage());
        }
    }

    //获取用户增量卡状态接口
    @GetMapping("/get-incremental-card-status")
    public JsonResult getIncrementalCardStatus(@RequestParam Integer userId) {
        // 调用 service 层方法获取用户增量卡状态
        User user = userService.getUserDoubleStatusById(userId);

        if (user != null && user.getHasIncrementalCard() != null) {
            // 创建一个 Map 来返回用户的增量卡状态
            Map<String, Object> status = new HashMap<>();
            status.put("hasIncrementalCard", user.getHasIncrementalCard());
            status.put("incrementalCardStartTime", user.getIncrementalCardStartTime());
            status.put("incrementalCardExpiryTime", user.getIncrementalCardExpiryTime());

            return JsonResult.success("获取成功", status);
        } else {
            return JsonResult.error("用户不存在或未设置增量卡");
        }
    }


    /**
     * 将种子大小加到用户上传量
     * @param userId 用户ID
     * @param torrentId 种子ID
     */
    @PostMapping("/addToUploadCount")
    public JsonResult addToUploadCount(@RequestParam Integer userId,
                                       @RequestParam Integer torrentId) {
        try {
            // 获取种子信息
            Torrent torrent = torrentService.getById(torrentId);
            if (torrent == null) {
                return JsonResult.error("种子不存在");
            }

            // 获取用户信息
            User user = userService.getById(userId);
            if (user == null) {
                return JsonResult.error("用户不存在");
            }

            // 更新上传量
            Float currentUpload = user.getUploadCount() != null ? user.getUploadCount() : 0;
            Float sizeGB = torrent.getSizeGB() != null ? torrent.getSizeGB().floatValue() : 0;


            //增量卡！！！！！！！！！！！！！！！！！
            // 判断增量卡有效性
            boolean hasValidCard = userService.hasValidIncrementalCard(userId);
              // 根据增量卡判断是否翻倍
            if (hasValidCard) {
                sizeGB = sizeGB * 2; // 如果有有效增量卡，则翻倍
            }
           //乘以满足活动的最大上传量系数
            // 获取上传量系数
            Double uploadCoeff = 1.0; // 默认为1（没有促销活动的情况）
            Promotions bestPromo = promotionsServiceImpl.getBestUploadPromo(userId);
            if (bestPromo != null) {
                uploadCoeff = bestPromo.getUploadCoeff();  // 获取促销活动的上传量系数
            }
            // 根据促销系数调整上传量
            sizeGB = sizeGB * uploadCoeff.floatValue();


            user.setUploadCount(currentUpload + sizeGB);

            // 保存到数据库
            userService.updateById(user);

            return JsonResult.success("上传量更新成功", user.getUploadCount());

        } catch (Exception e) {
            return JsonResult.error("更新上传量失败: " + e.getMessage());
        }
    }

    /**
     * 将种子大小加到用户下载量
     * @param userId 用户ID
     * @param torrentId 种子ID
     */
    @PostMapping("/addToDownloadCount")
    public JsonResult addToDownloadCount(@RequestParam Integer userId,
                                         @RequestParam Integer torrentId) {
        try {
            // 获取种子信息
            Torrent torrent = torrentService.getById(torrentId);
            if (torrent == null) {
                return JsonResult.error("种子不存在");
            }

            // 获取用户信息
            User user = userService.getById(userId);
            if (user == null) {
                return JsonResult.error("用户不存在");
            }

            // 更新下载量
            Float currentDownload = user.getDownloadCount() != null ? user.getDownloadCount() : 0;
            Float sizeGB = torrent.getSizeGB() != null ? torrent.getSizeGB().floatValue() : 0;

            //乘以满足活动的最小下载量系数
// 获取下载量系数
            Double downloadCoeff = 1.0; // 默认为1（没有促销活动的情况）
            List<Promotions> bestPromo = promotionsServiceImpl.getBestDownloadPromo(userId, torrentId);
            if (!bestPromo.isEmpty()) {
                Promotions theBestPromo = bestPromo.get(0);
                downloadCoeff = theBestPromo.getDownloadCoeff();  // 获取促销活动的上传量系数
            }
// 根据促销系数调整下载量
            sizeGB = sizeGB * downloadCoeff.floatValue();

            user.setDownloadCount(currentDownload + sizeGB);

            // 保存到数据库
            userService.updateById(user);

            return JsonResult.success("下载量更新成功", user.getDownloadCount());

        } catch (Exception e) {
            return JsonResult.error("更新下载量失败: " + e.getMessage());
        }
    }






}
